#include "synit.h"
#include <iostream>
using std::cout;
using std::endl;

static RewriteDB dbo5,db3,db10;
struct SYNIT_INIT_{
   SYNIT_INIT_()
   {
      dbo5.read_DB( CURDIR "dat/o5.db" );
      db3.read_DB( CURDIR"dat/3.db" );
      db10.read_DB( CURDIR"dat/10.db" );
   }
}SYNIT_INIT;

void report( CktInfo & ckt )
{
   cout <<"c lvl "<< ckt._max_level << "\t size "<< ckt.size()-ckt._andFlag <<  endl;
}
void report( StrashAIG & ckt )
{
   cout <<"c size "<< ckt.size()-ckt._andFlag <<  endl;
}
void rewrite( RewriteDB & db , InfoCut & in , StrashAIG & out )
{
//   cout<<"c rwt\t";
   Rewrite rwt( in );
   rwt.read_db( db );
   rwt.run();
   in.factor( out );
}
void rewrite( InfoCut & in , StrashAIG & out )
{
   rewrite( dbo5 , in , out );
}
void rewriteb( RewriteDB & db , InfoCut & in , StrashAIG & out )
{
//   cout<<"c rwb\t";
   Rewrite rwt( in );
   rwt.read_db( db );
   rwt.DIRECTION=1, rwt.REPLACEMENT=2;
   rwt.run();
   in.factor( out );
}
void rewriteb( InfoCut & in , StrashAIG & out )
{
   rewriteb( dbo5 , in , out );
}
void balance(  Balance & in , StrashAIG & out )
{
//   cout<<"c bal\t";
   in.run();
   in.factor( out );
}
void refactor(  Refactor & in , StrashAIG & out )
{
//   cout<<"c rf \t";
   in.run();
   in.factor( out );
}
void refactor_inv(  Refactor & rf , StrashAIG & out )
{
//   cout<<"c rfi\t";
   rf.INV = true;
   rf.run();
   rf.factor( out );
}
void synit( InfoCut & in , StrashAIG & out )
{
//   cout<< "c inp\t" ; report( in );
   {InfoCut c8;
   {Balance c7;
   {InfoCut c6;
   {Refactor c5;
   {Balance c4;
   {InfoCut c3;
   {Balance c2;
   {Refactor c1;
   {
         rewrite( dbo5 , 
                        in , c1 );}c1.init();//report(c1);
         refactor( 
                        c1 , c2 );}c2.init();//report(c2);
         balance( 
                        c2 , c3 );}c3.init();//report(c3);
         rewriteb( db10 , 
                        c3 , c4 );}c4.init();//report(c4);
         balance( 
                        c4 , c5 );}c5.init();//report(c5);
         refactor_inv( 
                        c5 , c6 );}c6.init();//report(c6);
         rewriteb( db3 , 
                        c6 , c7 );}c7.init();//report(c7);
         balance( 
                        c7 , c8 );}c8.init();//report(c8);
         rewriteb( dbo5 , 
                        c8 , out );} 
         //report( out );
}
